<script setup lang="ts">
import { nextTick, ref, watch } from 'vue';
import { MdPreview } from 'md-editor-v3';
import 'md-editor-v3/lib/style.css';
import { ElMessage } from 'element-plus';
import { httpStream, stopStream } from './api/ai';
import { useMessageStore } from './store/message';

interface Message {
  id: number
  thinking?: string
  content: string
  time: string
  type: 'ai' | 'self'
}


const messages = ref<Message[]>([])
const inputContent = ref('')
const loading = ref(false)
const thinkingStream = ref("")
const contentStream = ref("")
const isDeep = ref(false)
const messageStore = useMessageStore()
const activeHistoryId = ref<number | null>(null)
const currentHistory = ref<any>(null)

const getTargetMessages = () => {
  const history = messages.value.map(message => ({
    role: message.type === 'self' ? 'user' : 'assistant',
    content: message.content
  }))

  if (history.length > 20) {
    return history.slice(history.length - 20)
  }
  return history
}

const stopGeneration = async () => {
  stopStream();
}


const sendMessage = async () => {
  if (!inputContent.value.trim()) return


  if (loading.value) {
    ElMessage.warning('正在处理上一条消息，请稍后再试')
    return
  }

  messages.value.push({
    id: messages.value.length + 1,
    content: inputContent.value,
    time: new Date().toLocaleString(),
    type: 'self',
  })
  inputContent.value = ''

  try {
    loading.value = true
    await httpStream({
      body: {
        isDeep: isDeep.value,
        messages: getTargetMessages(),
      },
      handleNewToken: (token) => {
        try {
          const { reasoning_content, content } = JSON.parse(token);

          if (reasoning_content !== undefined) {
            thinkingStream.value += reasoning_content;
          }
          if (content !== undefined) {
            contentStream.value += content;
          }
        } catch (e) {
          contentStream.value += token;
        }
      }
    });
  } finally {
    if (contentStream.value || thinkingStream.value) {
      messages.value.push({
        id: new Date().getTime(),
        content: contentStream.value,
        thinking: thinkingStream.value,
        time: new Date().toLocaleString(),
        type: 'ai',
      })
    }
    loading.value = false
    thinkingStream.value = ""
    contentStream.value = ""
  }
}

const handleKeydown = (e: KeyboardEvent) => {
  if (e.key === 'Enter') {
    if (e.shiftKey) {
      // Shift + Enter 换行
      return
    }
    // 阻止默认的换行行为
    e.preventDefault()
    
    // 如果是中文输入法正在输入中，不发送
    if (e.isComposing) return
    
    sendMessage()
  }
}

const scrollToBottom = () => {
  nextTick(() => {
    const messageContainer = document.querySelector('#message-container')
    if (messageContainer) {
      messageContainer.scrollTop = messageContainer.scrollHeight
    }
  })
}

const deleteHistory = (id: number) => {
  const store = useMessageStore()
  store.history = store.history.filter(item => item.id !== id)
}

const chooseHistory = (id: number) => {
  const store = useMessageStore()
  activeHistoryId.value = id
  currentHistory.value = messageStore.history.find(item => item.id === id)
  const history = store.history.find(item => item.id === id)
  if (history) {
    messages.value = history.messages
  }
}

const updateHistory = () => {
  if(!activeHistoryId.value) return
  if(!currentHistory.value) {
    currentHistory.value = messageStore.history.find(item => item.id === activeHistoryId.value)
  }
  currentHistory.value.messages = messages.value
}

const startNewChat = () => {
  messages.value = []
  activeHistoryId.value = null
  currentHistory.value = null
}


watch([messages, thinkingStream, contentStream], () => {
  scrollToBottom()
  if(!activeHistoryId.value && messages.value.length > 0) {
    const historyId = new Date().getTime()
    const newHistory = {
      id: historyId,
      title: messages.value[0].content,
      messages: messages.value
    }
    messageStore.history = [...messageStore.history, newHistory]
    activeHistoryId.value = historyId
  }
  updateHistory()
}, { deep: true })



</script>

<template>
  <div class="common-layout">
    <el-container>
      <el-aside width="20%" max-width="200px">
        <h2 style="text-align: center; margin: 10px 0;font-size: 16px;">历史记录</h2>

        <el-button 
          type="primary" 
          style="width: 90%; margin: 0 auto 10px; display: block;"
          @click="startNewChat"
        >
          开始新会话
        </el-button>

        <ul class="history-list">
          <li v-for="message in messageStore.history" 
              :key="message.id" 
              class="history-item"
              :class="{ 'active': activeHistoryId === message.id }"
              @click="chooseHistory(message.id)">
            <div class="history-item-content">
              <span class="history-item-title">{{ message.title }}</span>
              <el-button type="danger" size="small" class="delete-btn" @click="deleteHistory(message.id)">删除</el-button>
            </div>
          </li>
        </ul>

      </el-aside>
      <el-container>
        <el-header>
          <h1 style="text-align: center;font-size: 20px;">DeepSeek流量源泉内部专用</h1>
        </el-header>
        <el-main>

          <div style="display: flex; flex-direction: column; height: calc(100vh - 100px);">
            <!-- 历史聊天记录 -->
            <div id="message-container" style="height: calc(100% - 150px);box-sizing: border-box;overflow-y: auto;">

              <div v-for="message in messages" :key="message.id" class="message" :class="message.type">
                <div class="avatar">
                  <img src="@/assets/user.svg" v-if="message.type === 'self'" alt="">
                  <img src="@/assets/deepseek.svg" v-if="message.type === 'ai'" alt="">
                </div>
                <div class="message-content">
                  <div class="time">{{ message.time }}</div>
                  <div class="content">
                    <div class="thinking" v-if="message.thinking">
                      <div class="title">思考内容</div>
                      <MdPreview v-model="message.thinking"  />
                    </div>
                    <div class="main">
                      <MdPreview v-model="message.content" />
                    </div>
                  </div>
                </div>
              </div>

              

              <div v-if="loading" class="message ai" >
                <div class="avatar">
                  <img src="@/assets/deepseek.svg">
                </div>
                <div v-if="!thinkingStream && !contentStream" style="width: 150px;" v-loading="true" element-loading-text="正在思考中..." class="loading-container">
                </div>
                <div v-else class="message-content">
                  <div class="time">{{ new Date().toLocaleTimeString() }}</div>

                  <div class="content">
                    <div class="thinking" v-if="thinkingStream">
                      <div class="title">思考内容</div>
                      <MdPreview v-model="thinkingStream" :preview="false" />
                    </div>
                    <div class="main" v-if="contentStream">
                      <MdPreview v-model="contentStream" :preview="false" />
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <div style="display: flex; flex-direction: column; height: 150px; align-items: center;">
              <div v-if="loading" style="display: flex; justify-content: center; margin-bottom: 10px;">
                <el-button type="danger" round @click="stopGeneration">停止生成</el-button>
              </div>
              <div style=" width: 50%; height: 100px; margin-top: 20px;border: 2px solid #dcdfe6; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);position: relative;padding: 8px;">
                <textarea 
                  v-model="inputContent"
                  placeholder="请输入内容" 
                  style="border: none; outline: none; background: none; width: 100%; height: calc(100% - 30px); resize: none;padding: 5px;"
                  @keydown="handleKeydown"
                ></textarea>
                <div style="position: absolute;bottom: 5px;width: 100%;padding: 5px;">
                  <div class="tool-button" :class="{'selected': isDeep}" @click="isDeep = !isDeep">深度推理</div>
                  <el-button type="primary" style="position: absolute; right: 18px; bottom: 0;" @click="sendMessage" :loading="loading">发送</el-button>
                </div>
              </div>
            </div>
          </div>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<style lang="scss" scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

.message {
  margin-bottom: 10px;
  display: flex;
  .md-editor-previewOnly {
    background-color: transparent!important;
    .md-editor-preview-wrapper {
      padding: 0 !important;
    }
  }

  .avatar {
    width: 40px;
    height: 100%;
    border-radius: 50%;
    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
    }
  }
  .message-content {
    padding: 10px;
    box-sizing: border-box;
    max-width: 90%;
    .time {

      font-size: 12px;
      color: #999;
      margin-bottom: 5px;
    }
    .content {
      font-size: 14px;
      color: #333;
      background: #e9ecf2;
      // width: fit-content;
      // max-width: 90%;
      border: 1px solid #dcdfe6;
      border-radius: 8px;
      box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
      padding: 5px 15px;
      .thinking {
        .title {
          font-size: 14px;
          font-weight: bold;
          color: #409EFF;
          margin-top: 10px;
        }
        margin-bottom: 10px;
        font-size: 12px;
        border-left: 2px solid #409EFF;
        padding-left: 10px;
      }
    }
  }
  &.self {
    .content {
      background: #f2f2f2;
    }
  }
}

.tool-button {
  border: 1px solid #dcdfe6;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);
  background: #e6e6e6;
  padding: 5px 15px;
  font-size: 14px;
  cursor: pointer;
  width: fit-content;
  &:hover {
    background: #f2f2f2;
  }
  &.selected {
    background: #c9e8ff;
  }
}

.history-list {
  list-style: none;
  padding: 0 10px;
}

.history-item {
  margin-bottom: 8px;
  border-radius: 6px;
  transition: all 0.2s ease;
  cursor: pointer;

  &:hover {
    background-color: #f5f7fa;
    .delete-btn {
      opacity: 1;
    }
  }

  &.active {
    background-color: #ecf5ff;
    .history-item-content {
      border-color: #409EFF;
    }
  }

  .history-item-content {
    padding: 10px;
    border: 1px solid #dcdfe6;
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    transition: all 0.2s ease;
  }

  .history-item-title {
    flex: 1;
    font-size: 14px;
    color: #333;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-right: 8px;
  }

  .delete-btn {
    opacity: 0;
    transition: opacity 0.2s ease;
    padding: 4px 8px;
    height: 24px;
  }
}

</style>
